package app

import (
	"container/list"
	"flag"
	"golang.org/x/net/websocket"
	"io"
	"log"
	"net/http"
	"strconv"
	"sync/atomic"
	"time"
)

const registerTimeoutSec = 10

// This is a temporary solution to avoid holding a zombie connection forever, by
// setting a 1 day timeout on reading from the WebSocket connection.
const wsReadTimeoutSec = 60 * 60 * 24

type Server struct {
	client *list.List
	maxRoomId int32
	room  *list.List
}

var (
	port *int
	server *Server
	)

func NewServer() *Server {
	server = &Server{client:&list.List{}};
	return server;
}

func (server *Server) NewRoom() *Room {
	server.maxRoomId =atomic.AddInt32(&server.maxRoomId,1)
	room := &Room{RoomId:int(server.maxRoomId)}
	server.room.PushBack(room);
	return room;
}

func (server *Server) NewClient(ws io.ReadWriteCloser) *Client {
	client := &Client{WsConn:ws}
	server.client.PushBack(client);
	return client;
}

func (c *Server) httpHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")             //允许访问所有域
	w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型
	w.Header().Set("content-type", "application/json")             //返回数据格式是json

	io.WriteString(w, "OK\n")
}


func (server *Server) wsHandler(ws *websocket.Conn) {

	client := server.NewClient(ws);
	for {
		if true {
			var msg wsClientMsg
			err := ws.SetReadDeadline(time.Now().Add(time.Duration(wsReadTimeoutSec) * time.Second))
			if err != nil {
				server.wsError("ws.SetReadDeadline error: "+err.Error(), ws)
				break
			}

			err = websocket.JSON.Receive(ws, &msg)
			log.Printf("Recv json %s",msg)
			if err != nil {
				if err.Error() != "EOF" {
					server.wsError("websocket.JSON.Receive error: "+err.Error(), ws)
				}
				log.Printf("Recv error%s",err.Error());
				break
			}
			switch msg.Cmd {
				  case "register":

				  case "push":
					  clientsdp := client.CreatePeer(msg.Sdp)
					  send(client.WsConn,clientsdp)
				  case  "pull":
					  clientsdp := client.CreatePeer(msg.Sdp)
					  client.LinkPeer(otherclient);
					  send(client.WsConn,clientsdp)
					break;
			}
		}
	}
	// This should be unnecessary but just be safe.
	ws.Close()
}

func (server *Server) wsError(msg string, ws *websocket.Conn) {
	sendServerErr(ws, msg)
}

func (server *Server) Init() {
	port = flag.Int("port", 8080, "http server port")
	flag.Parse()
}

func (server *Server) Start() {
	http.Handle("/ws", websocket.Handler(server.wsHandler))
	http.HandleFunc("/", server.httpHandler)
	err := http.ListenAndServe(":"+strconv.Itoa(*port), nil)
	if err != nil {
		panic(err)
	}
	return ;
}
